{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 👋🌍 Hello, world: Submit a Cirq job to IonQ\n",
    "\n",
    "In this notebook, we'll review the basics of Azure Quantum by submitting a simple *job*, or quantum program, to [IonQ](https://ionq.com/). We will use [Cirq](https://quantumai.google/cirq) to express the quantum job."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "## Submit a simple job to IonQ using Azure Quantum\n",
    "Azure Quantum provides several ways to express quantum programs. In this example we are using Cirq, but note that Q# and Qiskit are also supported. All code in this example will be written in Python.\n",
    "\n",
    "Let's begin. When you see a code block, hover over it and click the triangle play-button to execute it. To avoid any compilation issues, this should be done in order from top to bottom."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "### 1. Connect to the Azure Quantum workspace\n",
    "\n",
    "To connect to the Azure Quantum service, construct an instance of the `AzureQuantumService`. Note that it's imported from `azure.quantum.cirq`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from azure.quantum.cirq import AzureQuantumService\n",
    "\n",
    "service = AzureQuantumService(\n",
    "    resource_id = \"\",\n",
    "    location = \"\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "Let's see what providers and targets are enabled in this workspace with the following command:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false,
     "source_hidden": false
    },
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "outputs": [],
   "source": [
    "print(\"This workspace's targets:\")\n",
    "for target in service.targets():\n",
    "    print(\"-\", target.name)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "### ❕ Do you see `ionq.simulator` in your list of targets? If so, you're ready to keep going.\n",
    "\n",
    "Don't see it? You may need to add IonQ to your workspace to run this sample. Navigate to the **Providers** page in the portal and click **+Add** to add the IonQ provider. Don't worry, there's a free credits plan available."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "## IonQ: The quantum provider\n",
    "Azure Quantum partners with third-party companies to deliver solutions to quantum jobs. These company offerings are called *providers*. Each provider can offer multiple *targets* with different capabilities. See the table below for IonQ's targets.\n",
    "\n",
    "| Target name | Target ID | Number of qubits | Description |\n",
    "| --- | --- | --- | --- |\n",
    "| Quantum simulator | `ionq.simulator` | 29 qubits | IonQ's cloud-based idealized simulator. Free of cost. |\n",
    "| Aria 1 | `ionq.qpu.aria-1` | 23 qubits | IonQ's Aria 1 trapped-ion quantum computer. This is real quantum hardware, not a simulation. |\n",
    "| Quantum computer | `ionq.qpu` | 11 qubits | IonQ's trapped-ion quantum computer. This is real quantum hardware, not a simulation. |\n",
    "\n",
    "For this example, we will use `ionq.simulator`. To learn more about IonQ's targets, check out our [documentation](https://docs.microsoft.com/azure/quantum/provider-ionq)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. Build the quantum program\n",
    "\n",
    "Let's create a simple Cirq circuit to run."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import cirq\n",
    "\n",
    "q0 = cirq.LineQubit(0)\n",
    "circuit = cirq.Circuit(\n",
    "    cirq.H(q0),               # Apply an H-gate to q0\n",
    "    cirq.measure(q0)          # Measure q0\n",
    ")\n",
    "circuit"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "The circuit you built is a simple quantum random bit generator. With IonQ's idealized simulator, we will be able to calculate the probability of measuring a `1` or `0`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. Submit the quantum program to IonQ"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Using the IonQ simulator target, call \"run\" to submit the job. We'll\n",
    "# use 100 repetitions (simulated runs).\n",
    "job = service.targets(\"ionq.simulator\").submit(circuit, name=\"hello world-cirq-ionq\", repetitions=100)\n",
    "\n",
    "# Print the job ID.\n",
    "print(\"Job id:\", job.job_id())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "The job ID can be used to retrieve the results later using the [get_details function](https://docs.microsoft.com/azure/quantum/optimization-job-reference#jobdetails) or by viewing it under the **Job management** section of the portal."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "### 4. Obtain the job results\n",
    "Let's await the job execution by calling `job.results()`. This may take a minute or so ⏳. Your job is being packaged and sent to IonQ, where it will wait its turn to be run."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Await job results.\n",
    "print(\"Awaiting job results...\")\n",
    "result = job.results()\n",
    "\n",
    "# To view the probabilities computed for each Qubit state, you can print the result.\n",
    "print(\"Job finished. State probabilities:\")\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "You can also view a histogram of the results which computes hypothetical states based on the result's computed probabilities. Try running the next code cell multiple times to see the value change in accordance with the probabilities that the simulation computed."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false,
     "source_hidden": false
    },
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "outputs": [],
   "source": [
    "from cirq.vis import plot_state_histogram\n",
    "\n",
    "# Convert the result to a cirq result by \"measuring\" the returned\n",
    "# qubits a number of times equal to the specified number of repetitions.\n",
    "measurement = result.to_cirq_result()\n",
    "\n",
    "# We can now use Cirq to plot the results of the \"measurement.\"\n",
    "res = plot_state_histogram(measurement)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "**See the histogram above? Congratulations, you've submitted a job with Azure Quantum! 👏**\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 5. Estimate costs\n",
    "\n",
    "To estimate the costs of running this program on a simulator or hardware, you can use the `service.estimate_cost` method."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cost = service.estimate_cost(circuit, repetitions=100, target=\"ionq.qpu\")\n",
    "print(f\"Estimated cost: {cost.estimated_total} {cost.currency_code}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "### 6. Next steps\n",
    "Next, you can try running a program on IonQ's hardware target. Just replace `ionq.simulator` with `ionq.qpu`. Or try another sample by navigating back to the sample gallery. The same \"hello world\" sample can be run with different quantum providers by choosing another option in the gallery card drop-down menu. Don't worry - your work here is automatically saved.\n",
    "\n",
    "To learn more about submitting Cirq circuits to Azure Quantum, review [this documentation](https://docs.microsoft.com/azure/quantum/quickstart-microsoft-cirq?pivots=platform-ionq).\n",
    "\n",
    "To learn more about job pricing, review the [Azure Quantum documentation on job costs](https://docs.microsoft.com/azure/quantum/azure-quantum-job-costs)."
   ]
  }
 ],
 "metadata": {
  "kernel_info": {
   "name": "python3"
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "nteract": {
   "version": "nteract-front-end@1.0.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
